#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stddef.h>
#include "../ourhdr.h"

#define DB_INSERT   1
#define DB_REPLACE  2

#define IDXLEN_SZ   4
#define IDXLEN_MIN   6
#define IDXLEN_MAX   1024
#define SEP   ':'
#define DATLEN_MIN 2
#define DATLEN_MAX  1024
#define PTR_SZ  6
#define PTR_MAX 9999999
#define NHASH_DEF   137
#define FREE_OFF   0
#define HASH_OFF   PTR_SZ

typedef struct {
    int idxfd;
    int datfd;
    int oflag;
    char *idxbuf;
    char *datbuf;
    char *name;
    off_t idxoff;
    size_t idxlen;
    off_t datoff;
    size_t datlen;
    off_t ptrval;
    off_t ptroff;
    off_t chainoff;
    off_t hashoff;
    int nhash;
    long cnt_delok;
    long cnt_delerr;
    long cnt_fetchok;
    long cnt_fetcherr;
    long cnt_nextrec;
    long cnt_stor1;
    long cnt_stor2;
    long cnt_stor3;
    long cnt_stor4;
    long cnt_storerr;
} DB;

typedef unsigned long hash_t;

DB *db_open(const char*, int, int);
void db_close(DB *);
char *db_fetch(DB *, const char *);
int db_store(DB *, const char *, const char *, int);
int db_delete(DB *, const char *);
void db_rewind(DB *);
char *db_nextrec(DB *, char *);
void db_status(DB *);

DB *_db_alloc(int);
int _db_checkfree(DB *);
int _db_dodelete(DB *);
int _db_emptykey(char *);
int _db_find(DB *, const char *, int);
int _db_findfree(DB *, int, int);
int _db_free(DB *);
hash_t _db_hash(DB *, const char *);
char *_db_nextkey(DB *);
char *_db_readdat(DB *);
off_t _db_readidx(DB *, off_t);

off_t _db_readptr(DB *, off_t);
void _db_writedat(DB *, const char *, off_t, int);
void _db_writeidx(DB *, const char *, off_t, int, off_t);
void _db_writeptr(DB *, off_t, off_t);